package trb.complexshield.voxel;

import javax.vecmath.Point3i;
import no.hrp.hvrc.rad.calc.intersect.IntersectableBox;
import no.hrp.hvrc.utils.j3d.BBox;
import no.hrp.hvrc.utils.j3d.Mat4;
import no.hrp.hvrc.utils.j3d.Vec3;
import trb.complexshield.bool.distance.DistanceProducer;
import trb.complexshield.bool.model.AABBCreator;
import trb.complexshield.bool.model.DistanceCreator;

public class VoxelFromBool {

    public static VoxelGridBox createVoxel(Object boolModel, int dim) {
        BBox aabb = AABBCreator.createAABB(boolModel);
        Point3i dims = getDims(boolModel, dim);

        //System.out.println("aaaaaa dim " + dim + " " + dimx + " " + dimy + " " + dimz);

        IntersectableBox intersectableBox = new IntersectableBox(0, aabb.getLower(), aabb.getUpper(), new Mat4());
        VoxelGrid voxelGrid = new VoxelGrid(dims.x, dims.y, dims.z);
        VoxelGridBox voxelGridBox = new VoxelGridBox(voxelGrid, intersectableBox);
        VoxelFromBool.populate(voxelGridBox, DistanceCreator.createDistanceProducer(boolModel));
        return voxelGridBox;
    }

    public static VoxelGridBox createVoxel(Object boolModel, VoxelGrid voxelGrid) {
        BBox aabb = AABBCreator.createAABB(boolModel);
        IntersectableBox intersectableBox = new IntersectableBox(0, aabb.getLower(), aabb.getUpper(), new Mat4());
        VoxelGridBox voxelGridBox = new VoxelGridBox(voxelGrid, intersectableBox);
        VoxelFromBool.populate(voxelGridBox, DistanceCreator.createDistanceProducer(boolModel));
        return voxelGridBox;
    }

    public static void populate(VoxelGridBox voxelGridBox, DistanceProducer distanceProducer) {
        for (int z = 0; z < voxelGridBox.voxelGrid.zdim; z++) {
            for (int y = 0; y < voxelGridBox.voxelGrid.ydim; y++) {
                for (int x = 0; x < voxelGridBox.voxelGrid.xdim; x++) {
                    Vec3 world = voxelGridBox.getWorld(x + 0.5f, y + 0.5f, z + 0.5f);
                    float distance = distanceProducer.getDistance(world);
                    voxelGridBox.voxelGrid.setBitAtIndex(x, y, z, distance < 0);
                }
            }
        }
    }

    public static Point3i getDims(Object boolModel, int maxDim) {
        BBox aabb = AABBCreator.createAABB(boolModel);
        Vec3 size = aabb.getSize();
        float cellSize = size.max() / maxDim;
        int dimx = (int) Math.ceil(size.x / cellSize);
        int dimy = (int) Math.ceil(size.y / cellSize);
        int dimz = (int) Math.ceil(size.z / cellSize);
        return new Point3i(dimx, dimy, dimz);
    }
}
